package aceim.protocol.snuk182.xmppcrypto; import java.security.Security; import java.util.Arrays; import org.jivesoftware.smack.provider.ProviderManager; import org.jivesoftware.smackx.provider.EncryptedDataProvider; import aceim.api.dataentity.OnlineInfo; import aceim.api.dataentity.tkv.TKV; import aceim.api.service.ICoreProtocolCallback; import aceim.api.utils.Logger; import aceim.api.utils.Logger.LoggerLevel; import aceim.protocol.snuk182.xmpp.common.XMPPCommonService; import aceim.protocol.snuk182.xmpp.common.XMPPEntityAdapter; import aceim.protocol.snuk182.xmppcrypto.utils.ResourceUtils; import android.content.Context; import android.content.SharedPreferences.Editor; import android.os.Parcelable; import android.os.RemoteException; import android.text.TextUtils; public class XMPPService extends XMPPCommonService { @Override protected XMPPEntityAdapter initEntityAdapter() { return new XMPPCryptoEntityAdapter(); } public XMPPService(byte serviceId, String protocolUid, ICoreProtocolCallback callback, Context context) { super(serviceId, protocolUid, callback, context); } @Override protected void doSetFeature(String featureId, OnlineInfo info){ if (featureId.equals(XMPPCryptoApiConstants.FEATURE_ENCRYPTION_ON)) { encryptionOff(info); } else if (featureId.equals(XMPPCryptoApiConstants.FEATURE_ENCRYPTION_OFF)) { encryptionOn(info); } else if (featureId.equals(XMPPCryptoApiConstants.FEATURE_ADD_PUBLIC_KEY)) { processAddPublicKeyFeature(featureId, info); } else if (featureId.equals(XMPPCryptoApiConstants.FEATURE_REMOVE_PUBLIC_KEY)) { removeBuddyPGPKey(info); } else { super.doSetFeature(featureId, info); } } public void addBuddyPGPKey(OnlineInfo info, String pgp) { Editor e = getContext().getSharedPreferences(getProtocolUid(), 0).edit(); e.putString(ResourceUtils.BUDDY_PUBLIC_KEY_PREFIX + info.getProtocolUid(), pgp); e.commit(); info.getFeatures().remove(XMPPCryptoApiConstants.FEATURE_ADD_PUBLIC_KEY); info.getFeatures().putBoolean(XMPPCryptoApiConstants.FEATURE_ENCRYPTION_OFF, true); info.getFeatures().putBoolean(XMPPCryptoApiConstants.FEATURE_REMOVE_PUBLIC_KEY, true); //mRosterListener.getPresenceCache().put(info.getProtocolUid(), info); getCoreService().buddyStateChanged(Arrays.asList(info)); } public void removeBuddyPGPKey(OnlineInfo info) { Editor e = getContext().getSharedPreferences(getProtocolUid(), 0).edit(); e.remove(ResourceUtils.BUDDY_PUBLIC_KEY_PREFIX + info.getProtocolUid()); e.commit(); info.getFeatures().putBoolean(XMPPCryptoApiConstants.FEATURE_ADD_PUBLIC_KEY, true); info.getFeatures().remove(XMPPCryptoApiConstants.FEATURE_ENCRYPTION_OFF); info.getFeatures().remove(XMPPCryptoApiConstants.FEATURE_ENCRYPTION_ON); info.getFeatures().remove(XMPPCryptoApiConstants.FEATURE_REMOVE_PUBLIC_KEY); //mRosterListener.getPresenceCache().put(info.getProtocolUid(), info); getCoreService().buddyStateChanged(Arrays.asList(info)); } private void processAddPublicKeyFeature(String featureId, OnlineInfo info) { Parcelable[] p = info.getFeatures().getParcelableArray(featureId); if (p == null || p.length < 1) { Logger.log("No Parcelable at XMPP Add Buddy request", LoggerLevel.INFO); return; } String pgpKey = getContext().getString(R.string.pgp_key_file); String pgp = null; for (Parcelable pp : p) { TKV tkv = (TKV) pp; if (tkv.getKey().equals(pgpKey)) { pgp = tkv.getValue(); } } if (TextUtils.isEmpty(pgp)) { Logger.log("Empty PGP value in request", LoggerLevel.INFO); } else { addBuddyPGPKey(info, pgp); } } public void encryptionOn(OnlineInfo info) { String buddyPGPKey; EncryptedDataProvider edProvider = ((XMPPCryptoEntityAdapter)getEntityAdapter()).getEdProvider(); if (edProvider != null && (buddyPGPKey = getContext().getSharedPreferences(getProtocolUid(), 0).getString(ResourceUtils.BUDDY_PUBLIC_KEY_PREFIX + info.getProtocolUid(), null)) != null) { edProvider.getKeyStorage().put(info.getProtocolUid(), buddyPGPKey); } info.getFeatures().remove(XMPPCryptoApiConstants.FEATURE_ENCRYPTION_OFF); info.getFeatures().putBoolean(XMPPCryptoApiConstants.FEATURE_ENCRYPTION_ON, true); //mRosterListener.getPresenceCache().put(info.getProtocolUid(), info); getCoreService().buddyStateChanged(Arrays.asList(info)); } public void encryptionOff(OnlineInfo info) { EncryptedDataProvider edProvider = ((XMPPCryptoEntityAdapter)getEntityAdapter()).getEdProvider(); if (edProvider != null){ edProvider.getKeyStorage().put(info.getProtocolUid(), null); } info.getFeatures().remove(XMPPCryptoApiConstants.FEATURE_ENCRYPTION_ON); info.getFeatures().putBoolean(XMPPCryptoApiConstants.FEATURE_ENCRYPTION_OFF, true); //mRosterListener.getPresenceCache().put(info.getProtocolUid(), info); getCoreService().buddyStateChanged(Arrays.asList(info)); } @Override public void configure(ProviderManager pm) throws RemoteException { super.configure(pm); String pgpKey = getCoreService().requestPreference(ResourceUtils.KEY_PRIVATEKEY_FILE); String pgpKeyPassword = getCoreService().requestPreference(ResourceUtils.KEY_PRIVATEKEY_PASSWORD); EncryptedDataProvider edProvider; if (pgpKey != null && pgpKeyPassword != null){ edProvider = new EncryptedDataProvider(); edProvider.setMyKey(pgpKey); edProvider.setMyKeyPw(pgpKeyPassword); pm.addExtensionProvider("x", "jabber:x:signed", edProvider); pm.addExtensionProvider("x", "jabber:x:encrypted", edProvider); Security.addProvider(edProvider.getProvider()); } else { edProvider = null; pm.removeExtensionProvider("x", "jabber:x:signed"); pm.removeExtensionProvider("x", "jabber:x:encrypted"); } ((XMPPCryptoEntityAdapter)getEntityAdapter()).setEdProvider(edProvider); } }